<?php
namespace app\controller;

use app\BaseController;
use app\model\UserDepartmentRelationModel;
use think\facade\Db;
use think\facade\Request;
use think\Response;
/*
对比密码直接使用 password_verify('用户输入的明文密码', '数据库存储的哈希值');
if (!password_verify('用户输入的明文密码', '数据库存储的哈希值')) {
        密码错误
    } else {
        密码正确
    }

加密密码使用
$用户输入的明文密码 = 123456;
$加密后的密码 = password_hash($用户输入的明文密码, PASSWORD_BCRYPT);
*/
class Login extends BaseController
{
    public function index()
    {
        $data = Request::post();
        
        // 参数验证
        if (empty($data['username']) || empty($data['password'])) {
            return json(['code' => 400, 'msg' => '用户名和密码不能为空']);
        }

        // 查询用户
        $user = Db::name('user')
            ->where('username', $data['username'])
            ->where('status', 1)
            ->find();

        if (!$user) {
            return json(['code' => 401, 'msg' => '用户不存在或已禁用']);
        }

        // 验证密码
        if (!password_verify($data['password'], $user['password'])) {
            // 记录失败次数
            Db::name('user')
                ->where('id', $user['id'])
                ->inc('login_fail_times')
                ->update();
            return json(['code' => 401, 'msg' => '用户名或密码错误']);
        }



        // 获取设备类型（从请求参数中获取，默认为pc）
        $deviceType = $data['device_type'] ?? 'pc';
        
        // 生成登录token (使用简单的示例，实际应该用JWT等安全方案)
        //$token = "admin-accessToken-".md5($user['id'] . time() . uniqid());
        $tokenPrefix = ($deviceType === 'app') ? 'app-token' : 'pc-token';
        $token = $tokenPrefix . "-" . md5($user['id'] . time() . uniqid());

        // Token有效期48小时
        $expiresAt = date('Y-m-d H:i:s', time() + 48 * 3600);

        // 重置失败次数(保持原有逻辑兼容性)
        Db::name('user')
            ->where('id', $user['id'])
            ->update([
                'login_fail_times' => 0,  // 重置失败次数
            ]);
            
        // 清理所有过期token（任意用户登录时都清理）
        $this->cleanAllExpiredTokens();
        
        // 根据设备类型限制token数量
        $this->limitUserTokensByDeviceType($user['id'], $deviceType);
        
        // 将token存入新的tokens表，支持多设备登录
        try {
            $insertResult = Db::name('user_tokens')->insert([
                'user_id' => $user['id'],
                'token' => $token,
                'device_type' => $deviceType,
                'login_time' => date('Y-m-d H:i:s'),
                'expires_at' => $expiresAt,
                'status' => 1
            ]);
        } catch (Exception $e) {
            error_log("Token插入异常: " . $e->getMessage());
        }

        // 返回用户信息
        return json([
            'code' => 200,
            'msg' => '登录成功',
            'data' => [
                'token' => $token                
            ]
        ]);
    }

    public function userInfo()
    {
        // 从请求头获取token
        $token = Request::header('Authorization');
        if (empty($token)) {
            return json(['code' => 401, 'msg' => '未登录或token已过期']);
        }
        
        // 去掉 Bearer 前缀
        $token = str_replace('Bearer ', '', $token);
        
        // 从tokens表查询token信息
        $tokenInfo = Db::name('user_tokens')
            ->where('token', $token)
            ->where('status', 1)
            ->find();
            
        if (!$tokenInfo) {
            return json(['code' => 401, 'msg' => '未登录或token已过期']);
        }
        
        // 检查token是否过期
        if ($tokenInfo['expires_at'] && strtotime($tokenInfo['expires_at']) < time()) {
            // 标记token为已失效
            Db::name('user_tokens')
                ->where('id', $tokenInfo['id'])
                ->update(['status' => 2]);
            return json(['code' => 401, 'msg' => '登录已过期，请重新登录']);
        }
        
        // 更新最后活跃时间并延长有效期48小时
        $newExpiresAt = date('Y-m-d H:i:s', time() + 48 * 3600);
        Db::name('user_tokens')
            ->where('id', $tokenInfo['id'])
            ->update([
                'last_active_time' => date('Y-m-d H:i:s'),
                'expires_at' => $newExpiresAt
            ]);
        
        // 根据user_id查询用户基本信息
        $user = Db::name('user')
            ->where('id', $tokenInfo['user_id'])
            ->where('status', 1)
            ->find();
            
        if (!$user) {
            return json(['code' => 401, 'msg' => '用户不存在或已禁用']);
        }

        // 查询用户的权限
        $permissions = Db::name('user_permissions')
            ->where('user_id', $user['id'])
            ->column('permission');

        // 如果用户ID为1（管理员），返回所有权限
        if ($user['id'] == 1) {
            // 从数据库获取所有权限
            $permissions = Db::name('user_permissions')
                ->group('permission')
                ->column('permission');
            
            // 如果数据库中没有权限数据，给予基础权限
            if (empty($permissions)) {
                $permissions = ['Index']; // 只允许访问首页
            }
        }

        // 如果没有权限，给予基础权限（确保可以访问首页）
        if (empty($permissions)) {
            $permissions = ['Index']; // 只允许访问首页
        }

        $userDepartmentsRelationModel = new UserDepartmentRelationModel();
        $approvalAuthority = $userDepartmentsRelationModel->approvalAuthority($user['id']);

        // 返回用户信息
        return json([
            'code' => 200,
            'msg' => '获取成功',
            'data' => [
                'username' => $user['realname'], // 使用真实姓名
                'roles' => $permissions, // 返回权限作为角色
                'permissions' => $permissions, // 返回权限列表
                'avatar' => '/static/svg/avatar.svg',
                'userId' => $user['id'], // 添加用户ID
                'realname' => $user['realname'], // 添加真实姓名
                'approvalAuthority' => $approvalAuthority // 添加真实姓名
            ]
        ]);
    }

    /**
     * 获取用户部门信息
     */
    public function getUserDepartments()
    {
        // 从请求头获取token
        $token = Request::header('Authorization');
        if (empty($token)) {
            return json(['code' => 401, 'msg' => '未登录或token已过期']);
        }
        
        // 去掉 Bearer 前缀
        $token = str_replace('Bearer ', '', $token);
        
        // 从tokens表查询token信息
        $tokenInfo = Db::name('user_tokens')
            ->where('token', $token)
            ->where('status', 1)
            ->find();
            
        if (!$tokenInfo) {
            return json(['code' => 401, 'msg' => '未登录或token已过期']);
        }
        
        // 检查token是否过期
        if ($tokenInfo['expires_at'] && strtotime($tokenInfo['expires_at']) < time()) {
            // 标记token为已失效
            Db::name('user_tokens')
                ->where('id', $tokenInfo['id'])
                ->update(['status' => 2]);
            return json(['code' => 401, 'msg' => '登录已过期，请重新登录']);
        }
        
        // 更新最后活跃时间并延长有效期48小时
        $newExpiresAt = date('Y-m-d H:i:s', time() + 48 * 3600);
        Db::name('user_tokens')
            ->where('id', $tokenInfo['id'])
            ->update([
                'last_active_time' => date('Y-m-d H:i:s'),
                'expires_at' => $newExpiresAt
            ]);
        
        // 根据user_id查询用户基本信息
        $user = Db::name('user')
            ->where('id', $tokenInfo['user_id'])
            ->where('status', 1)
            ->find();
            
        if (!$user) {
            return json(['code' => 401, 'msg' => '用户不存在或已禁用']);
        }

        // 查询用户的部门信息
        $departments = Db::name('user_department_relation')
            ->alias('r')
            ->join('user_department d', 'r.department_id = d.id')
            ->where('r.user_id', $user['id'])
            ->field('d.name as dept_name, d.code as dept_code, r.is_leading')
            ->select();

        return json([
            'code' => 200,
            'msg' => '获取成功',
            'data' => $departments
        ]);
    }

    public function logout()
    {
        // 从请求头获取token
        $token = Request::header('Authorization');
        if (empty($token)) {
            return json(['code' => 401, 'msg' => '未登录']);
        }
        
        // 去掉 Bearer 前缀
        $token = str_replace('Bearer ', '', $token);
        
        // 将当前token标记为失效
        Db::name('user_tokens')
            ->where('token', $token)
            ->update(['status' => 2]);
            
        return json(['code' => 200, 'msg' => '退出登录成功']);
    }
    
    /**
     * 清理过期token（可以通过定时任务调用）
     */
    public function cleanExpiredTokens()
    {
        // 清理过期的token
        $expiredCount = Db::name('user_tokens')
            ->where('expires_at', '<', date('Y-m-d H:i:s'))
            ->where('status', 1)
            ->update(['status' => 2]);
            
        // 清理30天前的失效token记录
        $deletedCount = Db::name('user_tokens')
            ->where('status', 2)
            ->where('last_active_time', '<', date('Y-m-d H:i:s', time() - 30 * 24 * 3600))
            ->delete();
            
        return json([
            'code' => 200, 
            'msg' => '清理完成',
            'data' => [
                'expired_count' => $expiredCount,
                'deleted_count' => $deletedCount
            ]
        ]);
    }
    
    /**
     * 获取用户的所有登录设备
     */
    public function getUserDevices()
    {
        // 从请求头获取token
        $token = Request::header('Authorization');
        if (empty($token)) {
            return json(['code' => 401, 'msg' => '未登录']);
        }
        
        // 去掉 Bearer 前缀
        $token = str_replace('Bearer ', '', $token);
        
        // 获取当前用户ID
        $tokenInfo = Db::name('user_tokens')
            ->where('token', $token)
            ->where('status', 1)
            ->find();
            
        if (!$tokenInfo) {
            return json(['code' => 401, 'msg' => '未登录或token已过期']);
        }
        
        // 获取该用户的所有有效设备
        $devices = Db::name('user_tokens')
            ->where('user_id', $tokenInfo['user_id'])
            ->where('status', 1)
            ->field('id,device_info,login_time,last_active_time,expires_at')
            ->order('last_active_time desc')
            ->select();
            
        return json([
            'code' => 200,
            'msg' => '获取成功',
            'data' => $devices
        ]);
    }
    
    /**
     * 踢出指定设备
     */
    public function kickDevice()
    {
        $data = Request::post();
        
        if (empty($data['token_id'])) {
            return json(['code' => 400, 'msg' => '参数错误']);
        }
        
        // 从请求头获取当前token
        $currentToken = Request::header('Authorization');
        if (empty($currentToken)) {
            return json(['code' => 401, 'msg' => '未登录']);
        }
        
        $currentToken = str_replace('Bearer ', '', $currentToken);
        
        // 获取当前用户ID
        $currentTokenInfo = Db::name('user_tokens')
            ->where('token', $currentToken)
            ->where('status', 1)
            ->find();
            
        if (!$currentTokenInfo) {
            return json(['code' => 401, 'msg' => '未登录或token已过期']);
        }
        
        // 验证要踢出的设备是否属于当前用户
        $targetToken = Db::name('user_tokens')
            ->where('id', $data['token_id'])
            ->where('user_id', $currentTokenInfo['user_id'])
            ->find();
            
        if (!$targetToken) {
            return json(['code' => 403, 'msg' => '无权限操作']);
        }
        
        // 踢出设备（直接删除）
        Db::name('user_tokens')
            ->where('id', $data['token_id'])
            ->delete();
            
        return json(['code' => 200, 'msg' => '设备已踢出']);
    }
    
    /**
     * 清理所有过期token和失效token
     */
    private function cleanAllExpiredTokens()
    {
        // 直接删除所有过期的token
        Db::name('user_tokens')
            ->where('expires_at', '<', date('Y-m-d H:i:s'))
            ->delete();
            
        // 删除所有状态为2的失效token
        Db::name('user_tokens')
            ->where('status', 2)
            ->delete();
    }
    
    /**
     * 限制单用户token数量（在插入新token前执行）
     * @param int $userId 用户ID
     * @param int $maxTokens 最大token数量
     */
    private function limitUserTokens($userId, $maxTokens = 3)
    {
        // 获取该用户的有效token数量
        $tokenCount = Db::name('user_tokens')
            ->where('user_id', $userId)
            ->where('status', 1)
            ->count();
            
        // 只有当token数量达到3个时，才删除最早的1个为新token腾出空间
        if ($tokenCount >= $maxTokens) {
            $oldTokens = Db::name('user_tokens')
                ->where('user_id', $userId)
                ->where('status', 1)
                ->order('last_active_time asc')
                ->limit(1) // 只删除1个最早的
                ->column('id');
                
            if (!empty($oldTokens)) {
                Db::name('user_tokens')
                    ->where('id', 'in', $oldTokens)
                    ->delete();
            }
        }
    }

    /**
     * 根据设备类型限制用户token数量
     * @param int $userId 用户ID
     * @param string $deviceType 设备类型(pc/app)
     */
    private function limitUserTokensByDeviceType($userId, $deviceType)
    {
        // 设置不同设备类型的token限制
        $maxTokens = ($deviceType === 'app') ? 1 : 2; // APP最多1个，PC最多2个
        
        // 获取该用户指定设备类型的有效token数量
        $tokenCount = Db::name('user_tokens')
            ->where('user_id', $userId)
            ->where('device_type', $deviceType)
            ->where('status', 1)
            ->count();
            
        // 当token数量达到限制时，删除最早的token为新token腾出空间
        if ($tokenCount >= $maxTokens) {
            $deleteCount = $tokenCount - $maxTokens + 1; // 需要删除的数量
            $oldTokens = Db::name('user_tokens')
                ->where('user_id', $userId)
                ->where('device_type', $deviceType)
                ->where('status', 1)
                ->order('last_active_time asc')
                ->limit($deleteCount)
                ->column('id');
                
            if (!empty($oldTokens)) {
                Db::name('user_tokens')
                    ->where('id', 'in', $oldTokens)
                    ->delete();
            }
        }
    }
}
